package pub.guoxin.oops.auth.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import pub.guoxin.oops.auth.service.AuthenticationService;
import pub.guoxin.oops.auth.vo.AuthRegisterVo;
import pub.guoxin.oops.common.auth.service.AuthUserService;
import pub.guoxin.oops.common.auth.utils.BCryptPasswordEncoderUtils;
import pub.guoxin.oops.common.auth.utils.JwtTokenUtil;
import pub.guoxin.oops.model.User;
import pub.guoxin.oops.repository.CompanyRepository;
import pub.guoxin.oops.repository.UserRepository;
import pub.guoxin.oops.vo.ResultVo;
import pub.guoxin.oops.vo.ResultVoBuilder;

import java.util.Date;
import java.util.Objects;

/**
 * Created by guoxin on 17-11-14.
 */
@Slf4j
@Service
public class AuthenticationServiceImpl implements AuthenticationService {

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private CompanyRepository companyRepository;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private AuthUserService authUserService;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private ResultVoBuilder builder;

    /**
     * 一阶段注册-插入用户（插入时对密码加密）
     *
     * @param authenticationRequest
     * @return User
     */
    @Override
    public User addUser(AuthRegisterVo authenticationRequest) {
        User one = userRepository.findByMobile(authenticationRequest.getMobile());
        if (!Objects.isNull(one)) {
            log.info("该手机已经被注册");
            return null;
        }
        User user = authenticationRequest.createUser();
        user.setFirstLogin(false);
        User save = userRepository.save(user);
        UsernamePasswordAuthenticationToken AuthenticationToken = authenticationRequest.createUsernamePasswordAuthenticationToken();
        final Authentication authentication = authenticationManager.authenticate(AuthenticationToken);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        return save;
    }


    /**
     * 生成Token
     *
     * @param username
     * @param password
     * @return Token
     */
    @Override
    public String createAuthenticationToken(String username, String password) {
        // Perform the security
        final Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(
                        username,
                        password
                )
        );
        SecurityContextHolder.getContext().setAuthentication(authentication);

        // Reload password post-security so we can generate token
        User user = authUserService.getUserByUsername(username);
        return jwtTokenUtil.generateToken(user.getMobile());
    }

    /**
     * 刷新Token
     *
     * @param token
     * @return Token
     */
    @Override
    public String refreshAndGetAuthenticationToken(String token) {
        String username = jwtTokenUtil.getUsernameFromToken(token);
        User user = authUserService.getUserByUsername(username);

        if (!jwtTokenUtil.canTokenBeRefreshed(token, user.getLastPasswordResetDate())) {
            return null;
        }
        return jwtTokenUtil.generateToken(user.getMobile());
    }

    @Override
    public ResultVo modifyPassword(String username, String password) {
        User user = userRepository.findByMobile(username);
        if (Objects.isNull(user)){
            return builder.buildBadRequestResultInfo("该帐号不存在");
        }
        user.setLastPasswordResetDate(new Date());
        user.setPassword(BCryptPasswordEncoderUtils.encryptPassword(password));
        return builder.buildSuccessResultInfo();
    }

}
